<template>
    <el-dialog
        v-model="dialogVisible"
        :title="title"
        :width="width"
        align-center
        
        :close-on-click-modal="true"
        @close="handleClose"
    >
        <el-form
            ref="formRef"
            :model="formData"
            :rules="rules"
            label-width="120px"
            @submit.prevent="handleSubmit"
            @keydown="handleKeyDown"
        >
            <slot></slot>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="handleClose">取 消</el-button>
                <el-button type="primary" :loading="loading" @click="handleSubmit">
                    确 定
                </el-button>
            </span>
        </template>
    </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import type { FormInstance } from 'element-plus'

const props = defineProps({
    // 表单数据
    formData: {
        type: Object,
        required: true
    },
    // 表单验证规则
    rules: {
        type: Object,
        default: () => ({})
    },
    // 弹窗标题
    title: {
        type: String,
        default: '表单'
    },
    // 弹窗宽度
    width: {
        type: String,
        default: '500px'
    }
})

const emits = defineEmits(['submit', 'close'])

// 弹窗显示状态
const dialogVisible = ref(false)
// 提交loading状态
const loading = ref(false)
// 表单实例
const formRef = ref<FormInstance>()

// 打开弹窗
const open = () => {
    dialogVisible.value = true
}

// 关闭弹窗
const handleClose = () => {
    dialogVisible.value = false
    // 重置表单
    formRef.value?.resetFields()
    emits('close')
}

// 提交表单
const handleSubmit = async (e?: Event) => {
    // 阻止可能的默认提交行为
    e?.preventDefault()
    
    if (!formRef.value) return
    
    try {
        // 表单验证
        await formRef.value.validate()
        // 触发提交事件，传递loading状态引用，让父组件可以控制loading
        emits('submit', loading)
    } catch (error) {
        console.error('表单验证失败:', error)
    }
}

// 监听回车事件
const handleKeyDown = (e: KeyboardEvent) => {
    // 如果是回车键，且不是在textarea中
    if (e.key === 'Enter' && e.target instanceof HTMLElement && e.target.tagName !== 'TEXTAREA') {
        // 阻止默认行为
        e.preventDefault()
        // 如果不是在loading状态，则提交表单
        if (!loading.value) {
            handleSubmit()
        }
    }
}

// 监听弹窗关闭
watch(dialogVisible, (val) => {
    if (!val) {
        handleClose()
    }
})

// 暴露方法给父组件
defineExpose({
    open,
    close: handleClose,
    formRef
})
</script>

<style scoped>
.dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}
</style>
